package grame

import grails.converters.JSON
import org.apache.log4j.Level
import org.apache.log4j.LogManager

/**
 * @author Shining Wang <shiningwang@topca.com>
 */
class LoggerController {
    def grailsApplication

    def index() {
//        redirect(action: 'showLogLevel', params: params)
    }

    def changeLogLevel() {
        if (request.method == "POST") {
            String logLevel = params.level
            if (logLevel) {
                def appNameSpace = grailsApplication.config.grails.project.groupId
                logLevel = logLevel.toUpperCase();
                LogManager.getLogger("${appNameSpace}").setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger("grails.app.services.${appNameSpace}").setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger("grails.app.controllers.${appNameSpace}").setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger('org.codehaus.groovy.grails.web.servlet').setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger('org.codehaus.groovy.grails.web.pages').setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger('org.codehaus.groovy.grails.web.sitemesh').setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger('org.codehaus.groovy.grails.web.mapping.filter').setLevel((Level) (Level."${logLevel}"))
                LogManager.getLogger('org.codehaus.groovy.grails.web.mapping').setLevel((Level) (Level."${logLevel}"))
                if (params.loggerName) {
                    if (params.loggerName instanceof String[]) {
                        params.loggerName.each { String loggerName ->
                            LogManager.getLogger(loggerName).setLevel((Level) (Level."${logLevel}"))
                        }
                    } else {
                        String loggerName = params.loggerName
                        LogManager.getLogger(loggerName).setLevel((Level) (Level."${logLevel}"))
                    }
                }
            }
            String showSql = params.showSql
            if (showSql?.toLowerCase() == 'false') {
                LogManager.getLogger('org.hibernate.SQL').setLevel(Level.DEBUG)
                LogManager.getLogger('org.hibernate.type.descriptor.sql.BasicBinder').setLevel(Level.TRACE)
            } else {
                LogManager.getLogger('org.hibernate.SQL').setLevel(Level.ERROR)
                LogManager.getLogger('org.hibernate.type.descriptor.sql.BasicBinder').setLevel(Level.ERROR)
            }
        }
        if (params.test) {
            log.isTraceEnabled()
            log.isDebugEnabled()
            log.isInfoEnabled()
            log.isWarnEnabled()
            log.isErrorEnabled()
            log.isFatalEnabled()
        }

        render "true"
    }

    def showLogLevel() {
        def levelMap = [:]
        if (params.loggerName) {
            if (params.loggerName instanceof String[]) {
                params.loggerName.each { String loggerName ->
                    levelMap."${loggerName}" = LogManager.getLogger(loggerName).getLevel().toString()
                }
            } else {
                String loggerName = params.loggerName
                levelMap."${loggerName}" = LogManager.getLogger(loggerName).getLevel().toString()
            }
        } else {
            def appNameSpace = grailsApplication.config.grails.project.groupId
            render LogManager.getLogger("grails.app.controllers.${appNameSpace}").getLevel().toString()
            return
        }
        render levelMap as JSON
    }

    def show(String logger) {
        def _logger = LogManager.getLogger(logger)
        def result = [logger: _logger.name, level: _logger.level.toString()]
        log.trace("logger [" + result.logger + "] level is " + result.level)
        render result as JSON
    }

    def update(String logger, String level) {
        log.trace("try to update logger [" + logger + "] to " + level)
        Log4jGrameUtil.setLoggerLevel(logger, level)

        def _logger = LogManager.getLogger(logger)
        def result = [logger: _logger.name, level: _logger.level.toString()]
        log.trace("logger [" + result.logger + "] has been updated to " + result.level)
        render result as JSON
    }

    def save() {
        Log4jGrameUtil.store()
        render "OK"
    }

    def test() {
        log.error("test error level")
        log.info("test info level")
        log.debug("test debug level")
        log.trace("test trace level")
        def result = [:]
        result.errorEnabled = log.errorEnabled
        result.debugEnabled = log.debugEnabled
        result.infoEnabled = log.infoEnabled
        result.traceEnabled = log.traceEnabled
        render result as JSON
    }

}

